package mongodb.general.operator.config;

import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.convert.CustomConversions;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.MongoTransactionManager;
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;


@Configuration
public class MongoConfig extends AbstractMongoClientConfiguration {

    @Value("${spring.data.mongodb.database}")
    private String dataBase;

    @Value("${spring.data.mongodb.uri}")
    private String uri;

//    private String host;
//    private int port;
//    private String username;
//    private String password;
//    private String database;
//    @Bean
//    public MongoDbFactory mongoDbFactory() throws Exception {
//        /*// 无认证的初始化方法
//        return new SimpleMongoDbFactory(new MongoClient(host, port), database);*/
//        //有认证的初始化方法
//        ServerAddress serverAddress = new ServerAddress(host, port);
//        List<MongoCredential> mongoCredentialList = new ArrayList<>();
//        MongoCredential mongoCredential = MongoCredential.createCredential(username, database, password.toCharArray());
//        mongoCredentialList.add(mongoCredential);
//
//        return new SimpleMongoClientDatabaseFactory(new MongoClient(serverAddress, mongoCredentialList), database);
////        return new SimpleMongoDbFactory(new MongoClient(serverAddress, mongoCredentialList), database);
//    }


    @Override
    protected String getDatabaseName() {
        return dataBase;
    }

    @Override
    public MongoClient mongoClient() {
        final ConnectionString connectionString = new ConnectionString(uri);
        final MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
                .applyConnectionString(connectionString)
                .build();
        return MongoClients.create(mongoClientSettings);
    }

    //事务支持
    // * 增加此类 此外需要事务的方法上增加 @Transactional(rollbackFor = Exception.class) 开启事务
    @Bean
    MongoTransactionManager transactionManager(MongoDatabaseFactory mongoDbFactory) {
        return new MongoTransactionManager(mongoDbFactory);
    }
    //版本问题
//    @Bean
//    MongoTransactionManager transactionManager(MongoDbFactory mongoDbFactory) {
//        return new MongoTransactionManager(mongoDbFactory);
//    }
    // 去掉_class字段
    @Bean
    public MappingMongoConverter mappingMongoConverter(MongoDbFactory factory, MongoMappingContext context, BeanFactory beanFactory) {
        DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
        MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);
        try {
            mappingConverter.setCustomConversions(beanFactory.getBean(CustomConversions.class));
        } catch (NoSuchBeanDefinitionException ignore) {
        }
        // 去掉_class字段
        mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
        return mappingConverter;
    }
}
